#include <stdio.h>
#include <stdlib.h>
#include <string.h> //strdup
#include "config.h"
#include "token.h"
#include "http.h"
#include "stt.h"

//读取音频文件
//file: 音频文件路径
//size: 音频文件大小
//return: 音频文件内容, NULL 表示失败
char* load_audio_file(const char* file, size_t* size)
{
    //打开音频文件
    FILE* fp = fopen(file, "rb");
    if (!fp) {
        perror(file);
        return NULL;
    }
    //获取文件大小
    fseek(fp, 0, SEEK_END);
    *size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    //读取文件内容
    char* buffer = (char*)malloc(*size);
    if (!buffer) {
        perror("malloc");
        fclose(fp);
        return NULL;
    }
    fread(buffer, 1, *size, fp);
    fclose(fp);
    return buffer;
}

// 发送请求消息，并添加了dev_pid参数
// token: 获取的access token
// audio: 音频文件内容
// size: 音频文件大小
// dev_pid: 设备ID，用于指定识别的语言，例如1537为中文，1737为英文
// return: 响应消息正文, NULL 表示失败
static char* send_request(char* token, char* audio, size_t size, char* dev_pid) {
    // 根据dev_pid构建URL
    char* url = NULL;
    asprintf(&url, "http://vop.baidu.com/server_api?cuid=hqyj&token=%s&dev_pid=%s", token, dev_pid);

    // 创建HTTP头部，说明发送的数据是PCM格式的音频，采样率为16000
    struct curl_slist* headers = NULL;
    headers = curl_slist_append(headers, "Content-Type: audio/pcm; rate=16000");

    // 发送POST请求，音频数据作为请求体
    char* response = http_post(url, headers, audio, &size);

    // 清理分配的资源
    free(url);
    curl_slist_free_all(headers);

    return response;
}

//处理服务器返回的响应消息
static char* process_response(char* response)
{
    char* retval;

    //解析 JSON 响应
    cJSON *json = cJSON_Parse(response);
    if (!json) {
        fprintf(stderr, "解析 JSON 失败: [%s]\n", cJSON_GetErrorPtr());
        return NULL;
    }

    //判断err_no字段
    cJSON* err_no = cJSON_GetObjectItem(json, "err_no");
    if (!err_no) {
        fprintf(stderr, "err_no 字段不存在\n");
        cJSON_Delete(json);
        return NULL;
    }
    //判断err_no的值
    if (err_no->valueint != 0) {
        //打印错误信息
        cJSON* err_msg = cJSON_GetObjectItem(json, "err_msg");
        if (err_msg)
        {
            fprintf(stderr, "err_msg: %s\n", err_msg->valuestring);
        }
        cJSON_Delete(json);
        return NULL;
    }

    // 获取 "result" 字段中的第一个元素
    cJSON *result = cJSON_GetObjectItem(json, "result");
    if (!result) {
        fprintf(stderr, "JSON 格式错误: 找不到'result' 字段\n");
        cJSON_Delete(json);
        return NULL;
    }

    if (cJSON_GetArraySize(result) > 0) {
        // 获取第一个元素的 "content" 字段
        cJSON *content = cJSON_GetArrayItem(result, 0);
        //保存结果
        retval = strdup(content->valuestring);
    }

    cJSON_Delete(json);

    return retval;
}

//将音频数据转换为字符串
//audio: 存放音频数据的地址
//size:  音频数据大小
//返回值: 转换之后的字符串，转换失败返回NULL
char* speech_to_text(char* audio, size_t size, char* dev_pid)
{
    char* text;
    //读取配置信息，API KEY 和 SECRET KEY
    cJSON *config = read_config("config.json");
    if (!config) {
        printf("config: %s\n", cJSON_Print(config));
        return NULL;
    }

    cJSON* api_key = cJSON_GetObjectItem(config, "api_key");
    cJSON* secret_key = cJSON_GetObjectItem(config, "secret_key");
    if (!api_key ||!secret_key) {
        fprintf(stderr, "配置文件错误: 找不到 'api_key' 或'secret_key' 字段\n");
        cJSON_Delete(config);
        return NULL;
    }

    //获取token
    char* token = get_access_token(api_key->valuestring, secret_key->valuestring);
    cJSON_Delete(config);
    if (!token) {
        fprintf(stderr, "获取 token 失败\n");
        return NULL;
    }

    //调用百度语音识别 API
    char* response = send_request(token, audio, size, dev_pid);
    free(token);
    if (!response) {
        fprintf(stderr, "调用百度语音识别 API 失败\n");
        return NULL;
    }

    //处理服务器返回的响应消息
    text = process_response(response);

    free(response);

    return text;
}